package experiment;

import graphics.engine.RenderEngine;
import graphics.engine.RenderEngineType;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;

public class ExperimentManager 
{
	private Hashtable<String, Dataset> datasets;
	private Hashtable<Integer, DatasetOrder> datasetsOrder;
	
	private Experiment experiment;
	private ExperimentLogger experimentLogger;
	private RenderEngine renderEngine;
	
	
	private Iterator<ExperimentPhase> phaseIterator;
	private ExperimentPhase currentPhase;
	private Iterator<Dataset> datasetIterator;
	private Dataset currentDataset;
	private Iterator<Question> questionIterator;
	private Question currentQuestion;
	
	public ExperimentManager(RenderEngine renderEngine, int participantIndex)
	{
		this.datasets = new Hashtable<String, Dataset>();
		this.datasetsOrder = new Hashtable<Integer, DatasetOrder>();
		this.renderEngine = renderEngine;
		
		Participant currentParticipant = new Participant(participantIndex);
		this.setExperiment(new Experiment(currentParticipant));
		
		File datasetsFile = new File(Settings.experimentFolderPath+"datasets.csv");
		try{
			InputStream inputStream = new FileInputStream(datasetsFile); 
			InputStreamReader streamReader =new InputStreamReader(inputStream);
			BufferedReader br=new BufferedReader(streamReader);
			
			String ligne;
			ligne = br.readLine();
			
			while ( (ligne=br.readLine()) != null )
			{
				String[] subStr = ligne.split(";");
				
				String name = subStr[0].replace(";", "");
				String filePath = subStr[1].replace(";", "");
				int difficulty = Integer.parseInt(subStr[2].replace(";", ""));

				Dataset dataset = new Dataset(name, filePath, difficulty);
				this.datasets.put(name, dataset);
				//traj.Add(pos);
			}
			br.close(); 
		}		
		catch (Exception e){
			System.out.println(e.toString());
		}
		
		File questionsFile = new File(Settings.experimentFolderPath+"questions.csv");
		try{
			InputStream inputStream = new FileInputStream(questionsFile); 
			InputStreamReader streamReader =new InputStreamReader(inputStream);
			BufferedReader br=new BufferedReader(streamReader);
			
			String ligne;
			ligne = br.readLine();
			
			while ( (ligne=br.readLine()) != null )
			{
				String[] subStr = ligne.split(";");
				int ID = Integer.parseInt(subStr[0].replace(";",""));
				String questionLabel = subStr[1].replace(";", "");
				ArrayList<String> answers = new ArrayList<String>();
				String answer1 = subStr[2].replace(";", "");
				String answer2 = subStr[3].replace(";", "");
				String answer3 = subStr[4].replace(";", "");
				String answer4 = subStr[5].replace(";", "");
				String answer5 = subStr[6].replace(";", "");
				String answer6 = subStr[7].replace(";", "");
				answers.add(answer1);
				answers.add(answer2);
				answers.add(answer3);
				answers.add(answer4);
				answers.add(answer5);
				answers.add(answer6);
				int rightAnswerIndex = Integer.parseInt(subStr[8].replace(";", ""));
				String dataset = subStr[9].replace(";", "");
				String questionType = subStr[10].replace(";", "");
					
				Question question = new Question(ID, questionLabel, answers, rightAnswerIndex, questionType);
				this.datasets.get(dataset).addQuestion(question);
				
				//traj.Add(pos);
			}
			br.close(); 
		}		
		catch (Exception e){
			System.out.println(e.toString());
		}
		
		File datasetsOrderFile = new File(Settings.experimentFolderPath+"datasetsOrder.csv");
		try{
			InputStream inputStream = new FileInputStream(datasetsOrderFile); 
			InputStreamReader streamReader =new InputStreamReader(inputStream);
			BufferedReader br=new BufferedReader(streamReader);
			
			String ligne;
			ligne = br.readLine();
			
			while ( (ligne=br.readLine()) != null )
			{
				String[] subStr = ligne.split(";");

				Integer index = Integer.parseInt(subStr[0].replace(";", ""));
				String firstDataset = subStr[1].replace(";", "");
				String secondDataset = subStr[2].replace(";", "");
				String thirdDataset = subStr[3].replace(";", "");
				
				ArrayList<Dataset> datasetsSubList = new ArrayList<Dataset>();
				datasetsSubList.add(datasets.get(firstDataset));
				datasetsSubList.add(datasets.get(secondDataset));
				datasetsSubList.add(datasets.get(thirdDataset));
				
				DatasetOrder order = new DatasetOrder(index, datasetsSubList);
				
				this.datasetsOrder.put(index, order);
			}
			br.close(); 
		}		
		catch (Exception e){
			System.out.println(e.toString());
		}
		
		File participantsFile = new File(Settings.experimentFolderPath+"participants.csv");
		try{
			InputStream inputStream = new FileInputStream(participantsFile); 
			InputStreamReader streamReader =new InputStreamReader(inputStream);
			BufferedReader br=new BufferedReader(streamReader);
			
			String ligne;
			ligne = br.readLine();
			
			while ( (ligne=br.readLine()) != null )
			{
				String[] subStr = ligne.split(";");

				Integer index = Integer.parseInt(subStr[0].replace(";", ""));
				if(index == participantIndex)
				{
					String firstInterface = subStr[1].replace(";", "");
					Integer firstOrderIndex = Integer.parseInt(subStr[2].replace(";", ""));
					
					ExperimentPhase firstPhase;
					if(firstInterface.equals("Floorplan"))
					{
						firstPhase = new ExperimentPhase(datasetsOrder.get(firstOrderIndex), RenderEngineType.FloorPlan);
					}
					else
					{
						firstPhase = new ExperimentPhase(datasetsOrder.get(firstOrderIndex), RenderEngineType.Topological);
					}
					
					String secondInterface = subStr[3].replace(";", "");
					Integer secondOrderIndex = Integer.parseInt(subStr[4].replace(";", ""));
					
					ExperimentPhase secondPhase;
					if(secondInterface.equals("Floorplan"))
					{
						secondPhase = new ExperimentPhase(datasetsOrder.get(secondOrderIndex), RenderEngineType.FloorPlan);
					}
					else
					{
						secondPhase = new ExperimentPhase(datasetsOrder.get(secondOrderIndex), RenderEngineType.Topological);
					}

					this.getExperiment().addPhase(firstPhase);
					this.getExperiment().addPhase(secondPhase);
				}
			}
			br.close(); 
		}		
		catch (Exception e){
			System.out.println(e.toString());
		}
		this.experimentLogger = new ExperimentLogger(this.experiment);
	}

	public Experiment getExperiment() {
		return experiment;
	}

	public void setExperiment(Experiment experiment) {
		this.experiment = experiment;
	}
	
	public void startExperiment()
	{
		this.phaseIterator = this.experiment.getPhasesIterator();
		this.currentPhase = this.phaseIterator.next();
		this.renderEngine.setType(this.currentPhase.interfaceType);
		System.out.println(this.renderEngine.getType());
		this.datasetIterator = this.currentPhase.datasetOrder.datasets.iterator();
		this.currentDataset = this.datasetIterator.next();
		this.questionIterator = this.currentDataset.questions.iterator();
		this.currentQuestion = this.questionIterator.next();
	}

	public void endQuestion(int answerId)
	{
		this.experimentLogger.endQuestion(answerId);
		if(this.questionIterator.hasNext())
		{
			this.currentQuestion = questionIterator.next();
		}
		else if(datasetIterator.hasNext())
		{
			this.currentDataset = datasetIterator.next();
			this.questionIterator = currentDataset.questions.iterator();
			this.currentQuestion = this.questionIterator.next();
		}
		else if (this.phaseIterator.hasNext())
		{
			this.currentPhase = this.phaseIterator.next();
			this.renderEngine.setType(this.currentPhase.interfaceType);
			System.out.println(this.renderEngine.getType());
			
			this.datasetIterator = currentPhase.datasetOrder.datasets.iterator();
			this.currentDataset = this.datasetIterator.next();
			this.questionIterator = this.currentDataset.questions.iterator();
			this.currentQuestion = questionIterator.next();
		}			
		else
		{
			System.out.println("END");
		}
		this.renderEngine.draw = false;
	}
	public void startNextQuestion() {
		// TODO Auto-generated method stub
		ExperimentLog log = new ExperimentLog(currentQuestion);
		this.renderEngine.reset();
		this.experimentLogger.logs.add(log);
		this.experimentLogger.currentLog = log;
		// TODO Auto-generated method stub
		log.setStartTime(System.currentTimeMillis());
	}

	public ExperimentLogger getExperimentLogger() {
		// TODO Auto-generated method stub
		return this.experimentLogger;
	}
}
